A crypto FPGA project using an Arduino

[!] Important Note:

If during the process, your FPGA does not respond using Arduino IDE, and it'll surely happen, I invite you to download the VidorFPGARecovery repo from http://downloads.arduino.cc/tools/VidorFPGARecovery.zip and follow instructions.

Gitlab Repo : https://gitlab.com/PierreFontaine/arduivium

Introduction

As a student project, we had to realize a Trivium architecture for a ZedBoard which have a Xilinx FPGA. So we designed our architecture using VHDL and implemented it on our board using the Vivado tool chain.

In the picture below you can see how the initial board look like, and you'll figure out that it's not a tiny board !

../_images/zed.jpg

Today, I'd like to implement the same architecture on the Cyclone 10 FPGA provided by Intel. The board used which support it is an Arduino MKRVidor 4000 [1]. I bought this board because I really like how Arduino allows beginner to move forward by supplying good stuff for a decent price (At around 70€).

../_images/mkrvidor.jpg

There's not a lot of information about how to implement a project for this kind of board, we're a bit on our own. Fortunately with the information we got, we can start something !

I'd like to thank the author of SYSTEMES-EMBARQUES.FR and invite you to read his blog.

Usage of FPGAs

You'll surely heard about FPGA more oftently these days, indeed they are evolving in lot of different fields [Intel_usage]:

  • Automotive
  • Network
  • Vision
  • Computer & Storage
  • Medical
  • Military + Aerospace + Government

And just by checking news you can find articles [Register_FPGA] speaking about the usage of FPGA in Datacenter [Intel_PAC]. So, if you have a knowledge of the Intel's tools and connections like the PCI one, there's maybe something great to do !

../_images/intel_fpga_dc.jpeg

Board information

This board is developped to do plenty of things ! Communication is decoupled using a WiFi and Bluetooth modules, the usual field connectors are here (SPI, I2C ...), for image treatment you will be able to use the MIPI Camera connector and the HDMI connector to display any results ! There's also a mini-pci connector, so you can plug your board on your pc's motherboard !

../_images/Vidor_Mappa.jpg

A LiPo connector allow your board to be independant by plugging a battery.

But let's focus a bit deeper on the following trio : SAMD21, FPGA Memory and FPGA Cyclone 10.

Processor and FPGA

SAMD21

General purpose

The SAMD21 is a 32-bit ARM based Microcontrollers provided by the Atmel company[3].

Physical Spec

  • 32 to 64 pins
  • up to 256KB Flash
  • up to 32KB of SRAM
  • Max Frequ = 48 MHz

Periph Spec

  • 12 channel DMAC (Direct Memory Access Controller)
  • 12 channel Event System
  • up to 5 16-bit TC (Timer/Counter)
  • 3 24-bit TCC (Timer/Counters for Control)
  • 32 bit RTC (Real Time Counter)
  • Watchdog Timer
  • ...
  • up to 52 programmables I/O pins

../_images/SAMD21BD.png

SAMD21G18A

In order to find the exact version used among the 3 provided, we'll check the schematics [4], the relevent information is placed at the bottom of the principal rectangle shown.

../_images/MKVIDORSHM.png

Now we can check the part which describe the SAMD 21 G 18 A.

The nomenclature inform us that we have

  • 48 pins G,
  • 256KB 18
  • and we have the default variant A.
SAMD21G18A Pin Out

The following figure is not really relevent for the moment, but it can inform you about the positionning of the different pins of the board in a spatial representation, so using the previous scheme you know where any pin is plugged (spatial representation is important for me !).

../_images/SAMD21PO.png

FPGA Cyclone 10

Intel Cyclone 10C L 016 Y U 256 C8G

Note : The Arduino's website and the shematics pdf have both different informations, but pay attention at the inscriptions on the chip and it will remove all doubts
# Information gathered using Quartus
Revision Name	MKRVIDOR4000
Top-level Entity Name	MKRVIDOR4000_top
Family	Cyclone 10 LP
Device	10CL016YU256C8G
  • 10C : That's a Cyclone 10 (Obvious ...)
  • L : It's a variant LP, concretly it's a Cyclone 10 LP
  • 016 : We have 15.408 logic elements, this information is particularly important ! I'll explain that later !
  • Y : Standard voltage used (1.2V)
  • U : Ultra FineLine BGA (Seems that paths are extremly thin !)
  • 256 : Our chip has 256 pins
  • C : Dedicated to a commercial usage (T = 0° to 85° C)
  • 8 : Just an indicator about FPGA Fabric Speed Grade
  • G : RoHS-compliant packaging

../_images/intel_fpga_nom.png

Number of logic elements

An FPGA is an array containing a lot of logic element, those elements will be used and routed to create your architecture.

Now, the more your architecture is complex, the more element will be required.

Here for the project, I use 3% of the total amount of logic elements. Having said this, total amount used is totally dependent of your design and last but not least, the more you have free place remaining on your board, the more it will be easy for Quartus to route and place each elements !

Revision Name	MKRVIDOR4000
Top-level Entity Name	MKRVIDOR4000_top
Family	Cyclone 10 LP
Device	10CL016YU256C8G
Timing Models	Final
Total logic elements	386 / 15,408 ( 3 % )
Total registers	336
Total pins	138 / 163 ( 85 % )
Total virtual pins	0
Total memory bits	0 / 516,096 ( 0 % )
Embedded Multiplier 9-bit elements	0 / 112 ( 0 % )
Total PLLs	1 / 4 ( 25 % )

Quartus installation

For this projet we will install the Quartus Prime Lite Edition.

Vidor FPGA template

To begin our project let's create a repository. We will download a template delivered by the Arduino community from https://github.com/vidor-libraries/VidorFPGA. Note that, if you don't have the git command installed you can still download the project in a zip format.

Now you can open this project in Quartus and have a look to the different files :

[pfontaine@precision VidorFPGA]$ tree -L 2
.
├── constraints
│   └── MKRVIDOR4000
├── ip
│   ├── DVI_OUT
│   ├── FBST
│   ├── JTAG_BRIDGE
│   ├── MIPI_RX_ST
│   ├── NEOPIXEL
│   ├── PIO
│   ├── PWM
│   ├── QRCODE_FINDER
│   ├── QUAD_ENCODER
│   ├── SD_MODULATOR
│   ├── SDRAM_ARBITER
│   └── SYSTEM_PLL
├── LICENSE.txt
├── projects
│   └── MKRVIDOR4000_template
└── README.md

17 directories, 2 files

First things first we have a constraints file, this one is really important. Each code line in the constraints/MKRVIDOR4000/vidor_s_pins.qsf create a link between a FPGA pin and a Microprocessor pin.

To have a better understanding of this file, I will describe you a line, the one about the PIN_B16 of our Cyclone FPGA.

Step 1:

Check the vidor_c10_sch.pdf (page 2) (you can do a ctrl+f)

../_images/PIN_B16.png

Great, according to our documentation the IO_B6_B16 (B6 for 6th Banc, but you'll understand it later) is supposed to be linked to our SAMD21 PA09 IO.

Step 2:

Stay on the doc and search for PA09

../_images/PIN_PA09.png

Great, this pin match the SCL I/O ! But wait, you mean the SCL port on our jumper ?

Step 3:

Check for the jumper J5

../_images/J5.png

Yes ! We are on the right path !

(n.b : the SCL IO can be redirected from the I2C connector - Jumper J3)

Step 5:

Now you can say without any hesitation that bMKR_D[12] is actually our SCL IO from an HDL point of view !

set_location_assignment PIN_B16 -to bMKR_D[12]

Now if you prefer a GUI view that look like a Battleship game, here is the Pin Planner that'll confirm all our suppositions !

../_images/pin_planner.png

Fortunately, our friend who wrote the french articles has already reversed most of the IO ! https://systemes-embarques.fr/wp/brochage-connecteur-mkr-vidor-4000/

Back on the topic, we have an IP folder which contains some material architectures to play with. The one that seems pretty cool is the NEOPIXEL one, but we will see it a bit later !

The last folder is the one that hold our main files for our project.

Our Trivium architecture

I pushed the project sources here : https://gitlab.com/PierreFontaine/arduivium, you will find Trivium sources in TriviumHDL.

If you're wondering, what the hell is the Trivium algorithm, you'll find the specification right here : https://www.ecrypt.eu.org/stream/p3ciphers/trivium/trivium_p3.pdf

../_images/triv_spe.png

Our Trivium architecture is composed of multiple files imported in the MKRVIDOR4000_template folder.

[pfontaine@precision MKRVIDOR4000_template]$ ll | grep ".vhd"
-rw-rw-r--. 1 pfontaine pfontaine  1485 10 mars  22:44 key_iv_rom.vhd
-rw-rw-r--. 1 pfontaine pfontaine  1688 10 mars  22:53 reg_111_b.vhd
-rw-rw-r--. 1 pfontaine pfontaine  1705 10 mars  22:54 reg_x_b.vhd
-rw-rw-r--. 1 pfontaine pfontaine  2480 10 mars  23:09 T_ALU.vhd
-rw-rw-r--. 1 pfontaine pfontaine  2276 10 mars  22:51 top_trivium.vhd
-rw-rw-r--. 1 pfontaine pfontaine  3951 10 mars  23:05 trivium.vhd
-rw-rw-r--. 1 pfontaine pfontaine  3372 11 mars  12:05 uc_trivium.vhd

Until now, I've only learned how to develop HDL architecture using VHDL. I've been a bit surprised when I found that the template had been written using Verilog ! But no worries !

We're going to do an easy thing by using the GUI ! First I will transform my VHDL component into a Symbol File.

Now in File > New > Block Digram/Schematic File we can find our component !

../_images/ttriv.png

We place it on the grid !

We have 3 inputs to connect, including a special one which should be driven by an intern clock.

For the clock we're going to use the wOSC_CLK, the rst input will be linked on the pin 7 and controlled by a push button, the start_crypt input will also be linked to a push button using pin 1.

For the output side we'll only connect the gen_key to a LED on pin 6.

The block design should now be close to the following screenshot.

../_images/BLOCK_TRIV.png

Save you shematic.bdf, now we have to plug this piece of architecture in our template.

To do so, you'll search for the end of the code and try to match the following approach.

// PIECE OF CODE TO ADD

  TRIV_Schematic TRIV_Schematic_inst(
    .iTRIVCLK(wOSC_CLK),
	 .btnRST(bMKR_D[7]),
	 .btnSTART(bMKR_D[1]),
	 .oLED(bMKR_D[6])
  );

// PIECE OF CODE ALREADY EXISTING

  reg [5:0] rRESETCNT;

always @(posedge wMEM_CLK)
begin
  if (!rRESETCNT[5])
  begin
  rRESETCNT<=rRESETCNT+1;
  end
end

endmodule

Compile the architecture

Now that we are done with our architecture, and that we integrated our component we're going to compile the project.

You'll find in the toolbar the different compilation utilities.

../_images/toolbar_comp.png

For a real project, you should pass each step independantly without any warnings and errors.

Warnings will pop if some output are not used, but honestly it can sometime be really peculiar ! For this part, to be honest I have several warings.

../_images/compil_status.png

In the end, the important thing is to have the MKRVIDOR4000.ttf in the output_files directory.

Load bitsream on the board

Endianness

There's one thing not really obvious, you need to change the endianness of your .ttf file.

In order to achieve that part, I decided to use the utility provided by the author of systemes-embarques. It's written in Java, you'll find it here : https://systemes-embarques.fr/wp/wp-content/uploads/2018/10/ReverseByte_V2.zip

Arduino template

At this instant, we're going to download an Arduino template project that will allow us to send the bitstream easily toward the FPGA.

In your project folder, clone the following repo :

git clone https://github.com/vidor-libraries/VidorBoot.git

Then you should manipulate the files as following :

  • Create a project folder in src (ie : arduivium)
  • Copy/Paste each files except the boot.ttf one from src/ to our new folder
  • Copy/Paste the examples/RestoreFPGABootloader/RestoreFPGABootloader.ino file in the folder (the same as previously)
  • rename the src/arduivium/RestoreFPGABootloader.ino into src/arduivium/arduivium.ino.

Open a terminal, and move to the place where you downloaded the java utility.

java ReverseByte [..]/projects/MKRVIDOR4000_template/output_files/MKRVIDOR4000.ttf [..]/src/arduivium/boot.h

Arduino IDE

If you haven't install the Arduino IDE yet, you can install it from https://www.arduino.cc/en/main/software and follow instructions from this page https://www.arduino.cc/en/Guide/MKRVidor4000#toc2.

Otherwise, you can open your .ino file, it will load the entire project in the IDE.

Note that I had to change a line in VidorBoot.cpp

[---] 	#include "boot.ttf"
[+++]   #include "boot.h"

Then, plug your mkrvidor 4000 using an USB cable.

In tools make sure you have selected the right board manager.

Finally, you can verify + compile your project and transfer it on the board !

Prototyping

../_images/vidor_bb.svg

Test

You'll surely see the LED blink really quickly, but if we want to be sure that evrything went well we need to use an oscilloscope.

For this kind of application, I really like to use the BitScope Micro Analyser.

../_images/bitscope.png

  • Disable AUTO mode
  • set trigger on HIGH level
  • disable REPEAT mode

Then click TRACE and push the start button on the breadboard !

Here is the result :

../_images/bitscope_ardui.png

We can be confident with this result because it match our simulation done in the previous simulation tests :

../_images/rtl_simu_triv.png

Finally and obviously it's the same result as we get on the ZedBoard which was measured with a PicoScope:

../_images/pico_zb_res_triv.png

What's next ?

As you can see FPGA allows us to accelerate specific tasks ! We implemented a stream cipher algorithm, so it could be great to play with the MIPI Camera in order to send a ciphered stream that could be read by another devices and displayed on a screen !

Thanks for reading, hope it will help you in your futur projects using an MKRVidor 4000.

Stay tuned, the Arduino community is working to provide new IPs that will help a lot and will surely bring a lot of fun !